home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / cshel401 / part02 < prev    next >
Internet Message Format  |  1990-03-13  |  48KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i104: CShell 4.01A - alternative command interface, Part02/04
  5. Message-ID: <11771@xanth.cs.odu.edu>
  6. Date: 13 Mar 90 00:45:14 GMT
  7. Sender: news@cs.odu.edu
  8. Reply-To: page@Eng.Sun.COM (Bob Page)
  9. Lines: 2068
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: page@Eng.Sun.COM (Bob Page)
  15. Posting-number: Volume 90, Issue 104
  16. Archive-name: unix/cshell-4.01a/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 4)."
  25. # Contents:  src/comm1.c src/comm2.c src/sub.c
  26. # Wrapped by tadguy@xanth on Mon Mar 12 19:44:27 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/comm1.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/comm1.c'\"
  30. else
  31. echo shar: Extracting \"'src/comm1.c'\" \(16455 characters\)
  32. sed "s/^X//" >'src/comm1.c' <<'END_OF_FILE'
  33. X/*
  34. X * COMM1.C
  35. X *
  36. X * Matthew Dillon, August 1986
  37. X *
  38. X * Version 2.07M by Steve Drew 10-Sep-87
  39. X *
  40. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  41. X *
  42. X */
  43. X
  44. X#define DIR_SHORT 0x01
  45. X#define DIR_FILES 0x02
  46. X#define DIR_DIRS  0x04
  47. X#define DIR_NOCOL 0x08
  48. X#define DIR_NAMES 0x10
  49. X
  50. Xextern int has_wild;
  51. X
  52. X/*
  53. X    Parse the options specified in sw[]
  54. X    Setting a bit in global variable options
  55. X    for each one found
  56. X*/
  57. X
  58. Xget_opt(sw,count)
  59. Xchar *sw;
  60. Xint *count;
  61. X{
  62. Xregister char *c,*s;
  63. Xunsigned int l,i = 0;
  64. X
  65. Xoptions=0;
  66. Xwhile((++i < ac) && (av[i][0] == '-')) {
  67. X    for (c = av[i]+1; *c ; c++) {
  68. X        for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
  69. X        if (*s) options |= (1 << l);
  70. X        }
  71. X    }
  72. X*count = i;
  73. X}
  74. X
  75. Xdo_sleep()
  76. X{
  77. Xregister int i;
  78. X
  79. Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L);
  80. Xreturn 0;
  81. X}
  82. X
  83. Xdo_protect()
  84. X{
  85. Xregister long mask=0xf;
  86. Xregister char *s, *p;
  87. Xstatic char flags[]="DEWRAPSH";
  88. Xregister unsigned short i;
  89. X
  90. Xfor (s=av[--ac]; *s; s++)
  91. X    if (p=index(flags, toupper(*s))) mask^=(1 << (p-flags));
  92. X    else ierror(av[ac],500);
  93. Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
  94. Xreturn 0;
  95. X}
  96. X
  97. Xdo_filenote()
  98. X{
  99. Xchar *note=av[--ac];
  100. Xregister unsigned int i;
  101. X
  102. Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  103. Xreturn 0;
  104. X}
  105. X
  106. Xdo_cat()
  107. X{
  108. XFILE *fopen(), *fi;
  109. Xregister unsigned int lctr;
  110. Xunsigned int i;
  111. Xchar buf[256];
  112. X
  113. Xget_opt("n",&i);
  114. Xif (i>=ac) {
  115. X    if (has_wild) { printf("No files matching\n"); return 20; }
  116. X    lctr=0;
  117. X    while (gets(buf) && !dobreak()) {
  118. X        if (options) printf("%4d ",++lctr);
  119. X        puts(buf);
  120. X        }
  121. X    }
  122. Xfor (; i<ac; i++)
  123. X    if (fi = fopen (av[i], "r")) {
  124. X        lctr=0;
  125. X        while (fgets(buf,256,fi) && !dobreak()) {
  126. X            if (options) printf("%4d ",++lctr);
  127. X            printf("%s",buf);
  128. X            }
  129. X        fclose (fi);
  130. X        }
  131. X    else pError(av[i]);
  132. Xreturn 0;
  133. X}
  134. X
  135. Xdo_info()
  136. X{
  137. XBPTR lock;
  138. Xstruct InfoData *info;
  139. Xlong size, free;
  140. Xchar *p, buf[130], *state;
  141. Xstruct DirectoryEntry *de_head=NULL, *de;
  142. X
  143. Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
  144. XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  145. XMyprocess->pr_WindowPtr = (APTR)(-1);
  146. Xprintf ("Unit  Size  Bytes  Used Blk/By-Free Full Errs  Status    Name\n");
  147. Xfor (de=de_head; de; de=de->de_Next) {
  148. X    printf("%-5s",de->de_Name);
  149. X    if (lock=Lock(de->de_Name,ACCESS_READ)) {
  150. X        if (Info(lock, info)) {
  151. X        PathName(lock, buf, 128L);
  152. X        if (p=index(buf,':')) *p = '\0';
  153. X        size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
  154. X        free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
  155. X               info->id_BytesPerBlock)/ 1024;
  156. X        switch(info->id_DiskState) {
  157. X            case ID_WRITE_PROTECTED: state="Read Only "; break;
  158. X            case ID_VALIDATED:     state="Read/Write"; break;
  159. X            case ID_VALIDATING:     state="Validating"; break;
  160. X            }
  161. X        printf("%4ld%c%6ld%7ld%7ld%4ld%c%4ld%%%4ld  %s %s\n",
  162. X            (size>1024) ? ((size+512) >> 10) : size,
  163. X            (size>1024) ? 'M' : 'K',
  164. X            info->id_BytesPerBlock,
  165. X            info->id_NumBlocksUsed,
  166. X            info->id_NumBlocks-info->id_NumBlocksUsed,
  167. X            (free>1024) ? ((free+512) >> 10) : free,
  168. X            (free>1024) ? 'M' : 'K',
  169. X            (info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
  170. X            info->id_NumSoftErrors,
  171. X            state,
  172. X            buf);
  173. X        }
  174. X        else pError (de->de_Name);
  175. X        UnLock(lock);
  176. X        }
  177. X    else puts("  No disk present");
  178. X    }
  179. XFreeDAList(&de_head);
  180. XMyprocess->pr_WindowPtr = NULL;
  181. XFreeMem(info,(long)sizeof(struct InfoData));
  182. Xreturn 0;
  183. X}
  184. X
  185. X/* things shared with display_file */
  186. X
  187. XBPTR lastlock;
  188. Xint filecount, col;
  189. Xlong bytes, blocks;
  190. X
  191. X/*
  192. X * the args passed to do_dir will never be expanded
  193. X */
  194. Xdo_dir()
  195. X{
  196. Xint i, c, eac;
  197. Xchar **eav;
  198. X
  199. Xcol = filecount = 0;
  200. Xbytes = blocks = 0L;
  201. Xlastlock=NULL;
  202. X
  203. Xget_opt("sfdcn",&i);
  204. X
  205. Xif (ac == i) { ++ac; av[i]=""; }
  206. Xif (!(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
  207. X
  208. Xfor (; i<ac && !CHECKBREAK(); ++i)
  209. X    if (eav = expand(av[i], &eac)) {
  210. X        QuickSort(eav, eac);
  211. X        for(c=0; c<eac && !CHECKBREAK(); ++c)
  212. X            if (options & DIR_NAMES)
  213. X                puts(eav[c]);
  214. X            else
  215. X                display_file(eav[c]);
  216. X        free_expand (eav);
  217. X        }
  218. Xif (col) printf("\n");
  219. Xif (filecount>1) {
  220. X    blocks += filecount; /* account for dir blocks */
  221. X    printf(" %ld Blocks, %ld Bytes used in %d files\n",
  222. X        blocks, bytes, filecount);
  223. X    }
  224. Xif (lastlock) UnLock(lastlock);
  225. Xreturn 0;
  226. X}
  227. X
  228. Xdisplay_file(filestr)
  229. Xchar *filestr;
  230. X{
  231. Xlong atol();
  232. Xint isadir,slen;
  233. Xchar sc, *fi, *base, buf[130];
  234. XBPTR thislock;
  235. X
  236. Xbase=BaseName(filestr);
  237. Xsc = *base;
  238. X*base = '\0';
  239. Xthislock=Lock(filestr,SHARED_LOCK);
  240. X/* if (thislock==NULL) return; */
  241. Xif (lastlock==NULL || CompareLock(thislock,lastlock)) {
  242. X    if (col) printf("\n");
  243. X    col = 0;
  244. X    PathName(thislock, buf, 128L);
  245. X    printf("Directory of %s\n", buf);
  246. X    if (lastlock) UnLock(lastlock);
  247. X    lastlock=thislock;
  248. X    }
  249. Xelse UnLock(thislock);
  250. X*base = sc;
  251. Xslen = strlen(base);
  252. Xfi = base + slen + 1;
  253. Xisadir = (fi[12] =='D');
  254. X
  255. Xif (!(((options & DIR_FILES) && !isadir) ||
  256. X    ((options & DIR_DIRS) &&  isadir)))
  257. X        return;
  258. Xif (isadir && !(options & DIR_NOCOL)) printf ("\23333m");
  259. Xif (options & DIR_SHORT) {
  260. X    if (col==3 && slen>18) { printf("\n"); col = 0; }
  261. X    if (slen>18) { printf(" %-37s",base); col+= 2; }
  262. X        else { printf(" %-18s",base); col++; }
  263. X    if (col > 3) { printf("\n"); col=0; }
  264. X    }
  265. Xelse printf("   %-24s %s",base ,fi);
  266. Xif (isadir && !(options & DIR_NOCOL)) printf("\2330m");
  267. Xfi[16] = fi[21] = '\0';
  268. Xbytes  += atol(fi+10);
  269. Xblocks += atol(fi+17);
  270. Xfilecount++;
  271. X}
  272. X
  273. Xdo_quit()
  274. X{
  275. Xif (Src_stack) {
  276. X    Quit = 1;
  277. X    return(do_return());
  278. X    }
  279. Xmain_exit(0);
  280. X}
  281. X
  282. Xdo_echo()
  283. X{
  284. Xint i;
  285. X
  286. Xget_opt("n",&i);
  287. Xfor ( ; i<ac; i++) {
  288. X    printf("%s", av[i]);
  289. X    if (i != ac-1) printf(" ");
  290. X    }
  291. Xif (!options) printf("\n");
  292. Xreturn 0;
  293. X}
  294. X
  295. X/* gets a line from file, joining two lines if the first ends in '\' */
  296. X
  297. Xchar *myfgets(buf, buflen, file)
  298. Xchar *buf;
  299. XFILE *file;
  300. X{
  301. Xchar *bufptr=buf, *limit=buf+buflen;
  302. X
  303. Xdo {
  304. X    if (fgets(bufptr, limit-bufptr, file)==NULL) {
  305. X        if (bufptr != buf)
  306. X            fprintf(stderr,"Source: file ends in '\\'\n");
  307. X        return NULL;
  308. X        }
  309. X    bufptr = bufptr+strlen(bufptr)-2;
  310. X    } while (*bufptr=='\\');
  311. Xreturn buf;
  312. X}
  313. X
  314. Xdo_source(str)
  315. Xchar *str;
  316. X{
  317. Xregister FILE *fi;
  318. Xchar buf[256];
  319. Xint len;
  320. X
  321. Xif (Src_stack == MAXSRC) {
  322. X    ierror(NULL,217);
  323. X    return -1;
  324. X    }
  325. Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1;    }
  326. Xset_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  327. X++H_stack;
  328. XSrc_pos[Src_stack] = 0;
  329. XSrc_base[Src_stack] = (long)fi;
  330. X++Src_stack;
  331. Xwhile (myfgets (buf, 256, fi) && !dobreak()) {
  332. X    len = strlen(buf);
  333. X    buf[len-1] = '\0';
  334. X    Src_pos[Src_stack - 1] += len;
  335. X    if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
  336. X    exec_command (buf);
  337. X    }
  338. X--H_stack;
  339. X--Src_stack;
  340. Xif (forward_goto) ierror(NULL,501);
  341. Xforward_goto = 0;
  342. Xunset_level(LEVEL_LABEL + Src_stack);
  343. Xunset_var(LEVEL_SET, v_gotofwd);
  344. Xunset_var(LEVEL_SET, v_passed);
  345. Xfclose (fi);
  346. Xreturn 0;
  347. X}
  348. X
  349. X/*
  350. X * set process cwd name and $_cwd, if str != NULL also print it.
  351. X */
  352. Xdo_pwd(str)
  353. Xchar *str;
  354. X{
  355. Xchar pwd[130];
  356. X
  357. XPathName(Myprocess->pr_CurrentDir, pwd, 128L);
  358. Xif (str) puts(pwd);
  359. Xset_var(LEVEL_SET, v_cwd, pwd);
  360. X/* put the current dir name in our CLI task structure */
  361. XCtoBStr(pwd, Mycli->cli_SetName, 128L);
  362. Xreturn 0;
  363. X}
  364. X
  365. X/*
  366. X * CD
  367. X *
  368. X * CD(str, 0)      -do CD operation.
  369. X *
  370. X */
  371. X
  372. Xdo_cd(str)
  373. Xchar *str;
  374. X{
  375. XBPTR oldlock, filelock;
  376. X
  377. Xstr=next_word(str);
  378. Xif (!strcmp("..",str)) str="/";
  379. Xfilelock=Lock(str,ACCESS_READ);
  380. Xif (filelock==NULL) { pError(str); return 20; }
  381. Xif (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
  382. Xif (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  383. Xdo_pwd(NULL);
  384. Xreturn 0;
  385. X}
  386. X
  387. Xdo_mkdir()
  388. X{
  389. Xregister unsigned int i;
  390. XBPTR lock;
  391. X
  392. Xfor (i=1; i<ac; ++i) {
  393. X    if (exists(av[i])) ierror(av[i],203);
  394. X    else if (lock=CreateDir(av[i])) UnLock (lock);
  395. X    else pError(av[i]);
  396. X    }
  397. Xreturn 0;
  398. X}
  399. X
  400. Xdo_mv()
  401. X{
  402. Xchar *dest, buf[256];
  403. Xint dirflag;
  404. Xregister unsigned int i;
  405. X
  406. Xdirflag=isdir(dest=av[--ac]);
  407. Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  408. Xfor (i=1; i<ac; ++i) {
  409. X    strcpy(buf, dest);
  410. X    if (dirflag) TackOn(buf, BaseName(av[i]));
  411. X    if (Rename(av[i], buf)==0)
  412. X        { pError(av[i]); return -1; }
  413. X    }
  414. Xreturn 0;
  415. X}
  416. X
  417. Xint dirstoo;
  418. X
  419. Xall_args(args, action, dirsflag)
  420. Xchar *args;
  421. Xint (*action)();
  422. X{
  423. Xunsigned int i;
  424. X
  425. Xget_opt(args, &i);
  426. Xdirstoo=dirsflag;
  427. Xfor (; i<ac && !dobreak(); ++i)
  428. X    if (isdir(av[i])) {
  429. X        if (options & 1) recurse(av[i], action);
  430. X            else if (dirstoo) (*action)(av[i]);
  431. X        }
  432. X    else (*action)(av[i]);
  433. Xreturn 0;
  434. X}
  435. X
  436. Xchar *searchstring;
  437. X
  438. Xsearch_file(s)
  439. Xchar *s;
  440. X{
  441. XFILE *fopen(), *fi;
  442. Xregister char *p;
  443. Xregister unsigned int
  444. X    nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
  445. Xchar buf[256], lowbuf[256], searchit[256], first;
  446. X
  447. Xif (strcmp("STDIN",s)) fi=fopen(s,"r"); else fi=stdin;
  448. Xif (fi==NULL) { pError(s); return; }
  449. Xnocasedep=!(options & 2);
  450. Xlctr=0;
  451. Xif (!(options & 32)) printf("Examining %s...\n",s);
  452. Xstrcpy(searchit,searchstring);
  453. Xif (options & 4) strcat(searchit,"\n");
  454. Xlen=strlen(searchit);
  455. Xif (nocasedep) strupr(searchit);
  456. Xfirst=*searchit;
  457. Xwhile (fgets(buf,256,fi) && !dobreak()) {
  458. X    lctr++;
  459. X    if (options & 4) yesno=compare_ok(searchit, buf, options & 2);
  460. X    else {
  461. X        if (nocasedep) {
  462. X            strcpy(lowbuf,buf);
  463. X            strupr(lowbuf);
  464. X            p=lowbuf;
  465. X            }
  466. X        else p=buf;
  467. X        while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
  468. X        yesno= (p!=NULL);
  469. X        }
  470. X    if (yesno ^ excl) {
  471. X            /* default: print line numbers */
  472. X        if (!(options & 8)) printf("%4d ",lctr);
  473. X        printf("%s",buf);
  474. X        }
  475. X    }
  476. Xif (fi!=stdin) fclose (fi);
  477. X}
  478. X
  479. Xdo_search()
  480. X{
  481. Xsearchstring=av[--ac];
  482. Xall_args("rcwneq", search_file, 0);
  483. Xreturn 0;
  484. X}
  485. X
  486. Xrm_file(file)
  487. Xchar *file;
  488. X{
  489. Xif (has_wild) printf(" %s...",file);
  490. Xif (options & 2) SetProtection(file,0L);
  491. Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
  492. X}
  493. X
  494. Xdo_rm()
  495. X{
  496. Xall_args("rp", rm_file, 1);
  497. Xreturn 0;
  498. X}
  499. X
  500. Xrecurse(name, action)
  501. Xchar *name;
  502. Xint (*action)();
  503. X{
  504. Xregister BPTR lock, cwd;
  505. Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  506. Xchar *namecopy=malloc(256);
  507. X
  508. Xif (name[0] =='\0') return;
  509. Xnamecopy[0]=0;
  510. Xif (lock=Lock(name,ACCESS_READ)) {
  511. X    cwd =CurrentDir(lock);
  512. X    if (Examine(lock, fib))
  513. X    while (ExNext(lock, fib) && !CHECKBREAK()) {
  514. X        if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
  515. X        if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
  516. X        else strcpy(namecopy,fib->fib_FileName);
  517. X        }
  518. X    if (*namecopy) (*action)(namecopy);
  519. X    UnLock(CurrentDir(cwd));
  520. X    if (dirstoo) (*action)(name);
  521. X    }
  522. Xelse pError(name);
  523. Xfree(namecopy);
  524. XFreeMem(fib, (long)sizeof(FIB));
  525. X}
  526. X
  527. Xdo_history()
  528. X{
  529. Xregister struct HIST *hist;
  530. Xint i = H_tail_base;
  531. Xint len = (av[1]) ? strlen(av[1]) : 0;
  532. X
  533. Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev)
  534. X    if (len == 0 || !strncmp(av[1], hist->line, len))
  535. X        printf("%3d %s\n", i++, hist->line);
  536. Xreturn 0;
  537. X}
  538. X
  539. Xdo_mem()
  540. X{
  541. Xlong cfree, ffree;
  542. Xextern long AvailMem();
  543. X
  544. XForbid();
  545. Xcfree = AvailMem (MEMF_CHIP);
  546. Xffree = AvailMem (MEMF_FAST);
  547. XPermit();
  548. Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
  549. Xprintf("Total  Free: %ld\n", cfree+ffree);
  550. Xreturn 0;
  551. X}
  552. X
  553. Xdo_forline()
  554. X{
  555. Xchar vname[33], buf[256];
  556. Xregister unsigned short lctr;
  557. XFILE *f;
  558. Xchar *cstr;
  559. X
  560. Xstrcpy(vname,av[1]);
  561. Xf=fopen(av[2],"r");
  562. Xif (f==NULL) pError(av[2]);
  563. Xlctr=0;
  564. X++H_stack;
  565. Xcstr = compile_av (av, 3, ac, ' ', 0);
  566. Xwhile (fgets(buf,256,f) && !dobreak()) {
  567. X    buf[strlen(buf)-1]='\0';    /* remove CR */
  568. X    lctr++;
  569. X    set_var(LEVEL_SET, vname, buf);
  570. X    sprintf(buf,"%d",lctr);
  571. X    set_var(LEVEL_SET, v_linenum, buf);
  572. X    exec_command(cstr);
  573. X    }
  574. Xfclose(f);
  575. X--H_stack;
  576. Xfree (cstr);
  577. Xunset_var (LEVEL_SET, vname);
  578. Xunset_var (LEVEL_SET, v_linenum);
  579. Xreturn 0;
  580. X}
  581. X
  582. Xdo_fornum()
  583. X{
  584. Xchar vname[33], buf[16];
  585. Xint n1, n2, step, i, verbose;
  586. Xchar *cstr;
  587. X
  588. Xget_opt("vs",&i);
  589. Xverbose=(options & 1);
  590. Xstrcpy(vname,av[i++]);
  591. Xn1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  592. Xn2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  593. Xif (options & 2) {
  594. X    step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  595. X    }
  596. Xelse
  597. X    step=1;
  598. X++H_stack;
  599. Xcstr = compile_av (av, i, ac, ' ', 0);
  600. Xfor (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) {
  601. X    if (verbose) fprintf(stderr, "fornum: %d\n", i);
  602. X    sprintf(buf,"%d",i);
  603. X    set_var (LEVEL_SET, vname, buf);
  604. X    exec_command(cstr);
  605. X    }
  606. X--H_stack;
  607. Xfree (cstr);
  608. Xunset_var (LEVEL_SET, vname);
  609. Xreturn 0;
  610. X}
  611. X
  612. X/*
  613. X * foreach var_name  ( str str str str... str ) commands
  614. X * spacing is important (unfortunately)
  615. X *
  616. X * ac=0    1 2 3 4 5 6 7
  617. X * foreach i ( a b c ) echo $i
  618. X * foreach i ( *.c ) "echo -n "file ->";echo $i"
  619. X */
  620. X
  621. Xdo_foreach()
  622. X{
  623. Xregister int cstart, cend;
  624. Xregister char *cstr;
  625. Xchar **fav;
  626. Xchar vname[33];
  627. Xint i, verbose;
  628. X
  629. Xget_opt("v",&i);
  630. Xverbose=(options & 1);
  631. Xstrcpy(vname, av[i++]);
  632. Xif (*av[i] == '(') i++;
  633. Xcstart = i;
  634. Xwhile (i<ac && *av[i] != ')') i++;
  635. Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  636. X++H_stack;
  637. Xcend = i;
  638. X
  639. Xfav = (char **)malloc(sizeof(char *) * (ac));
  640. Xcstr = compile_av (av, cend + 1, ac, ' ', 0);
  641. X
  642. Xfor (i = cstart; i < cend; ++i) fav[i] = av[i];
  643. X
  644. Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  645. X    set_var (LEVEL_SET, vname, fav[i]);
  646. X    if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
  647. X    exec_command(cstr);
  648. X    }
  649. X--H_stack;
  650. Xfree (fav);
  651. Xfree (cstr);
  652. Xunset_var (LEVEL_SET, vname);
  653. Xreturn 0;
  654. X}
  655. X
  656. Xdo_forever(str)
  657. Xchar *str;
  658. X{
  659. Xint rcode = 0;
  660. Xchar *ptr = next_word(str);
  661. X
  662. X++H_stack;
  663. Xfor (;;) {
  664. X    if (CHECKBREAK()) { rcode = 20; break; }
  665. X    if (exec_command (ptr) < 0) {
  666. X        str = get_var(LEVEL_SET, v_lasterr);
  667. X        rcode = (str) ? atoi(str) : 20;
  668. X        break;
  669. X        }
  670. X    }
  671. X--H_stack;
  672. Xreturn rcode;
  673. X}
  674. X
  675. Xdo_exec(str)
  676. Xchar *str;
  677. X{
  678. Xreturn exec_command(next_word(str));
  679. X}
  680. X
  681. Xextern struct Window *w;
  682. Xextern struct IntuitionBase *IntuitionBase;
  683. X
  684. Xdo_window()
  685. X{
  686. Xlong x, y, maxwidth, maxheight, arg[5];
  687. Xunsigned int i;
  688. Xstruct Screen *screen;
  689. Xstruct Window *window;
  690. X
  691. Xget_opt("slfbaq", &i);
  692. Xif (options & 1)
  693. X    SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
  694. Xif (options & 2) {
  695. X    x=-w->LeftEdge;
  696. X    y=-w->TopEdge;
  697. X    MoveWindow(w,x,y);
  698. X    x=IntuitionBase->ActiveScreen->Width -w->Width;
  699. X    y=IntuitionBase->ActiveScreen->Height-w->Height;
  700. X    SizeWindow(w,x,y);
  701. X    }
  702. Xif (options & 4) WindowToFront(w);
  703. Xif (options & 8) WindowToBack(w);
  704. Xif (options & 16) ActivateWindow(w);
  705. Xif(ac >= 5) {
  706. X    for(i=1; i<5; i++) {
  707. X        arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
  708. X        }
  709. X    maxwidth = w->WScreen->Width;
  710. X    maxheight= w->WScreen->Height;
  711. X    if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
  712. X        ierror(NULL, 500);
  713. X        return 20;
  714. X        }
  715. X    x = -w->LeftEdge;
  716. X    y = -w->TopEdge;
  717. X    MoveWindow(w, x, y);
  718. X    x = arg[3] - w->Width;
  719. X    y = arg[4] - w->Height;
  720. X    SizeWindow(w, x, y);
  721. X    x = arg[1];
  722. X    y = arg[2];
  723. X    MoveWindow(w, x, y);
  724. X    }
  725. Xif(options & 32) {
  726. X    for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
  727. X        printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  728. X            screen->Title,
  729. X            screen->LeftEdge,
  730. X            screen->TopEdge,
  731. X            screen->Width,
  732. X            screen->Height
  733. X            );
  734. X        for (window=screen->FirstWindow; window; window=window->NextWindow) {
  735. X        printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  736. X            window->Title,
  737. X            window->LeftEdge,
  738. X            window->TopEdge,
  739. X            window->Width,
  740. X            window->Height
  741. X            );
  742. X        }
  743. X        }
  744. X    return 0;
  745. X    }
  746. XDelay(25L); /* pause 1/2 sec. before trying to print */
  747. Xprintf("\014");
  748. Xreturn 0;
  749. X}
  750. X
  751. Xsetsystemtime(ds)
  752. Xstruct DateStamp *ds;
  753. X{
  754. Xstruct timerequest tr;
  755. Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  756. X
  757. Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
  758. X    fprintf(stderr,"Clock error: can't open timer device\n");
  759. X    return;
  760. X    }
  761. Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  762. Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  763. Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  764. Xtr.tr_node.io_Message.mn_ReplyPort = NULL;
  765. Xtr.tr_node.io_Command = TR_SETSYSTIME;
  766. Xtr.tr_time.tv_secs = secs;
  767. Xtr.tr_time.tv_micro = 0L;
  768. Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
  769. XCloseDevice (&tr);
  770. X}
  771. X
  772. Xchar tday[10];
  773. X
  774. Xchar *dates(dss)
  775. Xstruct DateStamp *dss;
  776. X{
  777. Xstatic char timestr[40];
  778. Xchar tdate[10], ttime[10];
  779. Xstruct DateTime dt;
  780. Xstruct DateStamp *myds=&(dt.dat_Stamp);
  781. X
  782. Xdt.dat_Format=FORMAT_DOS;
  783. Xdt.dat_StrDay=tday;
  784. Xdt.dat_StrDate=tdate;
  785. Xdt.dat_StrTime=ttime;
  786. Xdt.dat_Flags=NULL;
  787. Xmyds->ds_Days=dss->ds_Days;
  788. Xmyds->ds_Minute=dss->ds_Minute;
  789. Xmyds->ds_Tick=dss->ds_Tick;
  790. XStamptoStr(&dt);
  791. Xsprintf(timestr,"%s %s\n",tdate,ttime);
  792. Xtimestr[18]='\n';
  793. Xtimestr[19]='\0';    /* protection against bad timestamped files */
  794. Xreturn timestr;
  795. X}
  796. X
  797. Xdo_date()
  798. X{
  799. Xstruct DateStamp dss;
  800. Xregister unsigned short i;
  801. Xstruct DateTime dt;
  802. X
  803. Xdt.dat_Format=FORMAT_DOS;
  804. Xif (ac==1) {
  805. X    DateStamp(&dss);
  806. X    printf("%s %s",tday,dates(&dss));
  807. X    }
  808. Xelse {
  809. X    DateStamp(& (dt.dat_Stamp));
  810. X    for (i=1; i<ac; i++) {
  811. X        dt.dat_StrDate=NULL;
  812. X        dt.dat_StrTime=NULL;
  813. X        dt.dat_Flags=DTF_FUTURE;
  814. X        if (index(av[i],':')) dt.dat_StrTime=av[i];
  815. X            else dt.dat_StrDate=av[i];
  816. X        if (StrtoStamp(&dt)) ierror(av[i],500);
  817. X        }
  818. X    setsystemtime( & (dt.dat_Stamp) );
  819. X    }
  820. Xreturn 0;
  821. X}
  822. END_OF_FILE
  823. if test 16455 -ne `wc -c <'src/comm1.c'`; then
  824.     echo shar: \"'src/comm1.c'\" unpacked with wrong size!
  825. fi
  826. # end of 'src/comm1.c'
  827. fi
  828. if test -f 'src/comm2.c' -a "${1}" != "-c" ; then 
  829.   echo shar: Will not clobber existing file \"'src/comm2.c'\"
  830. else
  831. echo shar: Extracting \"'src/comm2.c'\" \(13095 characters\)
  832. sed "s/^X//" >'src/comm2.c' <<'END_OF_FILE'
  833. X/*
  834. X * COMM2.C
  835. X *
  836. X * (c)1986 Matthew Dillon     9 October 1986
  837. X *
  838. X * Version 2.07M by Steve Drew 10-Sep-87
  839. X *
  840. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  841. X *
  842. X */
  843. X
  844. X/* Casting conveniences */
  845. X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  846. X#define PROC(task)              ((struct Process *)task)
  847. X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  848. X
  849. X/* Externs */
  850. Xextern int has_wild;                    /* flag set if any arg has a ? or * */
  851. X
  852. X/* globals */
  853. Xint cp_update;
  854. Xint cp_date;
  855. X
  856. Xdo_abortline()
  857. X{
  858. XExec_abortline = 1;
  859. Xreturn 0;
  860. X}
  861. X
  862. Xdo_return()
  863. X{
  864. Xregister int retcode=(ac<2 ? 0 : atoi(av[1]));
  865. X   Exec_abortline = 1;
  866. X   if (Src_stack) {
  867. X       FILE *ptr = (FILE *)Src_base[Src_stack - 1];
  868. X       ptr->_bp = ptr->_bend;
  869. X       ptr->_flags |= _EOF;
  870. X/*     fseek (Src_base[Src_stack - 1], 0L, 2); */
  871. X      return retcode;
  872. X   } else main_exit(retcode);
  873. X}
  874. X
  875. X/*
  876. X * STRHEAD
  877. X *
  878. X * place a string into a variable removing everything after and including
  879. X * the 'break' character
  880. X *
  881. X * strhead varname breakchar string
  882. X *
  883. X */
  884. X
  885. Xdo_strhead()
  886. X{
  887. Xchar *s;
  888. Xif (s=index(av[3],*av[2])) *s='\0';
  889. Xset_var (LEVEL_SET, av[1], av[3]);
  890. Xreturn 0;
  891. X}
  892. X
  893. Xdo_strtail()
  894. X{
  895. Xchar *s;
  896. Xif (s=index(av[3],*av[2])) s++; else s=av[3];
  897. Xset_var (LEVEL_SET, av[1], s);
  898. Xreturn 0;
  899. X}
  900. X
  901. Xlong dptrtosecs(d)
  902. Xstruct DPTR *d;
  903. X{
  904. Xregister struct DateStamp *ds=(&d->fib->fib_Date);
  905. Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  906. X}
  907. X
  908. Xlong timeof(s)
  909. Xchar *s;
  910. X{
  911. Xstruct DPTR *d;
  912. Xint dummy;
  913. Xlong n;
  914. X
  915. Xif ( (d=dopen(s,&dummy))==NULL ) return 0L;
  916. Xn=dptrtosecs(d);
  917. Xdclose(d);
  918. Xreturn n;
  919. X}
  920. X
  921. X/*
  922. X * if -f file (exists) or:
  923. X *
  924. X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  925. X * nothing
  926. X * a string
  927. X * a value (begins w/ number)
  928. X */
  929. X
  930. Xdo_if(garbage, com)
  931. Xchar *garbage;
  932. X{
  933. Xint result;
  934. Xint i;
  935. X
  936. Xswitch (com) {
  937. X    case 0:
  938. X    if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
  939. X    else {
  940. X        get_opt("rftmdvn",&i);
  941. X        result=evalif(i);
  942. X        If_base[If_stack++]=(options & 64 ? result : !result);
  943. X        }
  944. X    break;
  945. X    case 1:
  946. X    if (If_stack > 1 && If_base[If_stack - 2]) break;
  947. X    if (If_stack) If_base[If_stack - 1] ^= 1;
  948. X    break;
  949. X    case 2:
  950. X    if (If_stack) --If_stack;
  951. X    break;
  952. X     }
  953. Xdisable = (If_stack) ? If_base[If_stack - 1] : 0;
  954. Xif (If_stack >= MAXIF) {
  955. X    fprintf(stderr,"If's too deep\n");
  956. X    disable = If_stack = 0;
  957. X    return -1;
  958. X    }
  959. Xif (forward_goto) disable = If_base[If_stack - 1] = 0;
  960. Xreturn 0;
  961. X}
  962. X
  963. Xevalif(i)
  964. Xregister unsigned int i;
  965. X{
  966. Xchar c;
  967. Xlong num, t0, isint;
  968. Xlong AvailMem();
  969. X
  970. Xswitch(options & ~64) {
  971. X    case 0:
  972. X    if (ac-i != 3) return (ac>i && *av[i]);
  973. X    num  = Atol(av[i]);
  974. X    isint  = ! IoErr();
  975. X    num -= Atol(av[i+2]);
  976. X    isint &= ! IoErr();
  977. X    if (!isint) num=strcmp(av[i],av[i+2]);
  978. X    if (num < 0)       c='<';
  979. X    else if (num > 0)  c='>';
  980. X    else if (num == 0) c='=';
  981. X    return index(av[i+1], c) != NULL;
  982. X    case 1:
  983. X    return do_rpn(NULL,i);
  984. X    case 2:
  985. X    return exists(av[i]);
  986. X    case 4:
  987. X    t0=timeof(av[i++]);
  988. X    for ( ; i<ac ; i++)
  989. X        if (t0<=timeof(av[i])) return 1;
  990. X    return 0;
  991. X    case 8:
  992. X    return (AvailMem( (long)MEMF_FAST )!=0);
  993. X    case 16:
  994. X    return (isdir(av[i])!=0);
  995. X    case 32:
  996. X    return (get_var(LEVEL_SET,av[i]) != 0);
  997. X    default:
  998. X    ierror(NULL,500);
  999. X    return 0;
  1000. X    }
  1001. X}
  1002. X
  1003. Xdo_label()
  1004. X{
  1005. X   char aseek[32];
  1006. X
  1007. X   if (Src_stack == 0) {
  1008. X      ierror (NULL, 502);
  1009. X      return (-1);
  1010. X   }
  1011. X
  1012. X   sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  1013. X   set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  1014. X   if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  1015. X      forward_goto = 0;
  1016. X   return 0;
  1017. X}
  1018. X
  1019. Xdo_goto()
  1020. X{
  1021. X   int new;
  1022. X   long pos;
  1023. X   char *lab;
  1024. X
  1025. X   if (Src_stack == 0) {
  1026. X      ierror (NULL, 502);
  1027. X   } else {
  1028. X      lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  1029. X      if (lab == NULL) {
  1030. X         forward_goto = 1;
  1031. X         set_var (LEVEL_SET, v_gotofwd, av[1]);
  1032. X         return(0);
  1033. X      } else {
  1034. X         pos = atoi(lab);
  1035. X         fseek (Src_base[Src_stack - 1], pos, 0);
  1036. X         Src_pos[Src_stack - 1] = pos;
  1037. X         new = atoi(next_word(lab));
  1038. X         for (; If_stack < new; ++If_stack)
  1039. X            If_base[If_stack] = 0;
  1040. X         If_stack = new;
  1041. X      }
  1042. X   }
  1043. X   Exec_abortline = 1;
  1044. X   return (0);      /* Don't execute rest of this line */
  1045. X}
  1046. X
  1047. X
  1048. Xdo_inc(garbage, com)
  1049. Xchar *garbage;
  1050. X{
  1051. Xchar *var, num[32];
  1052. X
  1053. Xif (ac>2) com *= atoi(av[2]);
  1054. Xif (var = get_var (LEVEL_SET, av[1])) {
  1055. X    sprintf (num, "%d", atoi(var)+com);
  1056. X    set_var (LEVEL_SET, av[1], num);
  1057. X    }
  1058. Xreturn 0;
  1059. X}
  1060. X
  1061. Xdo_input()
  1062. X{
  1063. Xchar in[256], *p,*s;
  1064. Xunsigned int i;
  1065. X
  1066. Xfor (i=1; i < ac; ++i)
  1067. X    if (gets(in)) {
  1068. X    for(p = in; *p; p = s) {
  1069. X        s = next_word(p);
  1070. X        if (*s) *(s-1) = 0xA0;
  1071. X        }
  1072. X    set_var (LEVEL_SET, av[i], in);
  1073. X    }
  1074. Xreturn 0;
  1075. X}
  1076. X
  1077. Xdo_ver()
  1078. X{
  1079. Xextern char shellname[];
  1080. X
  1081. Xputs(shellname);
  1082. Xputs("(c)1986 Matthew Dillon\n\
  1083. XManx (M) versions by Steve Drew\n\
  1084. XARP (A) versions by Carlo Borreo & Cesare Dieni\n");
  1085. Xreturn 0;
  1086. X}
  1087. X
  1088. Xdo_ps()
  1089. X{
  1090. X/* this code fragment based on ps.c command by Dewi Williams */
  1091. X
  1092. Xregister int    count;        /* loop variable        */
  1093. Xstruct Task    *task;        /* EXEC descriptor        */
  1094. Xchar        strbuf[64+1];    /* scratch for btocstr()    */
  1095. Xchar        cmd[40+1];    /* holds cmd name        */
  1096. Xlong ncli;
  1097. X
  1098. Xprintf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  1099. XForbid();
  1100. X
  1101. Xncli=(long)FindCLI(0L);
  1102. Xfor (count = 1; count <= ncli ; count++)
  1103. X        /* or just assume 20?*/
  1104. X    if (task = (struct Task *)FindCLI((long)count)) {
  1105. X    if (task==NULL) continue;
  1106. X    /* Sanity check just in case */
  1107. X    if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
  1108. X                            /* or complain? */
  1109. X    BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1110. X    BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  1111. X    printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
  1112. X        count,
  1113. X        cmd,
  1114. X        task->tc_Node.ln_Name,
  1115. X        task->tc_Node.ln_Pri,
  1116. X        task,
  1117. X        strbuf);
  1118. X    }
  1119. XPermit();
  1120. Xreturn 0;
  1121. X}
  1122. X
  1123. X/*
  1124. X * CP [-d] [-u] file file
  1125. X * CP [-d] [-u] file file file... destdir
  1126. X * CP [-r][-u][-d] dir dir dir... destdir
  1127. X */
  1128. X
  1129. Xchar *errstr;          /* let's be alittle more informative */
  1130. X
  1131. Xdo_copy()
  1132. X{
  1133. Xregister int recur, ierr;
  1134. Xregister char *destname;
  1135. Xregister char destisdir;
  1136. Xregister FIB *fib;
  1137. Xint i;
  1138. X
  1139. Xerrstr = "";
  1140. Xierr = 0;
  1141. X
  1142. Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1143. X
  1144. Xget_opt("rud",&i);
  1145. Xrecur     = (options & 0x01);
  1146. Xcp_update = (options & 0x02);
  1147. Xcp_date   = (!(options & 0x04)); /* the default is keep orignal file date */
  1148. X
  1149. Xdestname = av[ac - 1];
  1150. X
  1151. Xif (ac < i + 2) {
  1152. X    ierr = 500;
  1153. X    goto done;
  1154. X    }
  1155. Xdestisdir = isdir(destname);
  1156. Xif (ac > i + 2 && !destisdir) {
  1157. X    ierr = 507;
  1158. X    goto done;
  1159. X    }
  1160. X
  1161. X/*
  1162. X * copy set:                        reduce to:
  1163. X *    file to file                     file to file
  1164. X *    dir  to file (NOT ALLOWED)
  1165. X *    file to dir                      dir to dir
  1166. X *    dir  to dir                      dir to dir
  1167. X *
  1168. X */
  1169. X
  1170. Xfor (; i<ac-1 && !dobreak(); ++i) {
  1171. X    short srcisdir = isdir(av[i]);
  1172. X    if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  1173. X        continue;             /* getting copied if specified */
  1174. X                         /* from wild expansion */
  1175. X    if (srcisdir) {
  1176. X        BPTR srcdir, destdir;
  1177. X        if (!destisdir) {
  1178. X            if (exists(destname)) {
  1179. X                ierr = 507;    /* disallow dir to file */
  1180. X                goto done;
  1181. X                }
  1182. X            if (destdir = CreateDir(destname)) UnLock(destdir);
  1183. X            destisdir = 1;
  1184. X            }
  1185. X        if (!(destdir = Lock(destname, ACCESS_READ))) {
  1186. X            ierr = 205;
  1187. X            errstr = destname;
  1188. X            goto done;
  1189. X            }
  1190. X        if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  1191. X            ierr = 205;
  1192. X            errstr = av[i];
  1193. X            UnLock(destdir);
  1194. X            goto done;
  1195. X            }
  1196. X        ierr = copydir(srcdir, destdir, recur);
  1197. X        UnLock(srcdir);
  1198. X        UnLock(destdir);
  1199. X        if (ierr) break;
  1200. X        }
  1201. X    else {        /* FILE to DIR,   FILE to FILE   */
  1202. X        BPTR destdir, srcdir, tmp;
  1203. X        char *destfilename;
  1204. X
  1205. X        srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  1206. X
  1207. X        if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  1208. X            if (tmp) UnLock(tmp);
  1209. X            ierr = 205;
  1210. X            errstr = av[i];
  1211. X            goto done;
  1212. X            }
  1213. X        UnLock(tmp);
  1214. X        if (destisdir) {
  1215. X            destdir = Lock(destname, ACCESS_READ);
  1216. X            destfilename = fib->fib_FileName;
  1217. X            }
  1218. X        else {
  1219. X            destdir = srcdir;
  1220. X            destfilename = destname;
  1221. X            }
  1222. X        printf(" %s..",av[i]);
  1223. X        fflush(stdout);
  1224. X        ierr = copyfile(av[i], srcdir, destfilename, destdir);
  1225. X        if (destisdir) UnLock(destdir);
  1226. X        if (ierr) break;
  1227. X        }
  1228. X    }
  1229. X
  1230. Xdone:
  1231. X
  1232. XFreeMem(fib, (long)sizeof(FIB));
  1233. Xif (ierr) {
  1234. X    ierror(errstr, ierr);
  1235. X    return(20);
  1236. X    }
  1237. Xreturn 0;
  1238. X}
  1239. X
  1240. X
  1241. Xcopydir(srcdir, destdir, recur)
  1242. Xregister BPTR srcdir, destdir;
  1243. X{
  1244. X   BPTR cwd;
  1245. X   register FIB *srcfib;
  1246. X   register BPTR destlock, srclock;
  1247. X   int ierr;
  1248. X   static int level;
  1249. X
  1250. X   level++;
  1251. X   ierr = 0;
  1252. X   srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1253. X   if (Examine(srcdir, srcfib)) {
  1254. X      while (ExNext(srcdir, srcfib)) {
  1255. X         if (CHECKBREAK())
  1256. X            break;
  1257. X         if (srcfib->fib_DirEntryType < 0) {
  1258. X            printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  1259. X            fflush(stdout);
  1260. X            ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  1261. X            if (ierr)
  1262. X               break;
  1263. X         } else {
  1264. X            if (recur) {
  1265. X               cwd = CurrentDir(srcdir);
  1266. X               if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  1267. X                  CurrentDir(destdir);
  1268. X                  if (!(destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE))) {
  1269. X                     destlock = CreateDir(srcfib->fib_FileName);
  1270. X                     printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  1271. X                                " ",srcfib->fib_FileName);
  1272. X
  1273. X                        /* UnLock and re Lock if newly created
  1274. X                           for file_date() to work properly
  1275. X                        */
  1276. X                     if (destlock) UnLock(destlock);
  1277. X                     destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE);
  1278. X                  }
  1279. X                  else
  1280. X                     printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  1281. X                  if (destlock) {
  1282. X                     ierr = copydir(srclock, destlock, recur);
  1283. X                     UnLock(destlock);
  1284. X                  } else {
  1285. X                     ierr = (int)((long)IoErr());
  1286. X                  }
  1287. X                  UnLock(srclock);
  1288. X               } else {
  1289. X                  ierr = (int)((long)IoErr());
  1290. X               }
  1291. X               CurrentDir(cwd);
  1292. X               if (ierr)
  1293. X                  break;
  1294. X            }
  1295. X         }
  1296. X      }
  1297. X   } else {
  1298. X      ierr = (int)((long)IoErr());
  1299. X   }
  1300. X   --level;
  1301. X   FreeMem(srcfib, (long)sizeof(FIB));
  1302. X   return(ierr);
  1303. X}
  1304. X
  1305. X
  1306. Xcopyfile(srcname, srcdir, destname, destdir)
  1307. Xchar *srcname, *destname;
  1308. XBPTR srcdir, destdir;
  1309. X{
  1310. XBPTR cwd;
  1311. XBPTR f1, f2;
  1312. Xlong i;
  1313. Xint stat,ierr;
  1314. Xchar *buf;
  1315. Xstruct DPTR *dp, *dps = NULL;
  1316. X
  1317. Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1318. X    { ierr = 103; goto fail; }
  1319. Xierr = 0;
  1320. Xcwd = CurrentDir(srcdir);
  1321. Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  1322. X    { errstr = srcname; ierr = 205; goto fail; }
  1323. Xdps = dopen(srcname,&stat);
  1324. XCurrentDir(destdir);
  1325. Xif (cp_update)
  1326. X    {
  1327. X    dp=dopen(destname, &stat);
  1328. X    if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  1329. X        !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  1330. X        { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  1331. X    dclose(dp);
  1332. X    }
  1333. Xif ((f2=Open(destname, MODE_NEWFILE))==NULL)
  1334. X    { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  1335. Xwhile (i = Read(f1, buf, 8192L))
  1336. X    if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
  1337. XClose(f2);
  1338. XClose(f1);
  1339. Xif (!ierr)
  1340. X    {
  1341. X    if (cp_date) file_date(&dps->fib->fib_Date, destname);
  1342. X    printf("..copied\n");
  1343. X    }
  1344. Xelse DeleteFile(destname);
  1345. Xfail:
  1346. X dclose(dps);
  1347. X if (buf) FreeMem(buf, 8192L);
  1348. X CurrentDir(cwd);
  1349. X return(ierr);
  1350. X}
  1351. X
  1352. Xdo_touch()
  1353. X{
  1354. Xstruct DateStamp ds;
  1355. Xregister unsigned int i;
  1356. XDateStamp(&ds);
  1357. Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
  1358. Xreturn 0;
  1359. X}
  1360. X
  1361. Xfile_date(date,name)
  1362. Xstruct DateStamp *date;
  1363. Xchar *name;
  1364. X{
  1365. Xlong packargs[7];
  1366. XUBYTE *ptr;
  1367. Xstruct MsgPort *task;
  1368. XBPTR dirlock;
  1369. Xstruct DPTR *tmp;
  1370. Xint stat;
  1371. X
  1372. Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  1373. Xif (tmp = dopen(name, &stat)) {
  1374. X    dirlock = ParentDir(tmp->lock);
  1375. X    ptr=AllocMem(65L,MEMF_PUBLIC);
  1376. X    CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  1377. X    dclose(tmp);
  1378. X    packargs[1]=dirlock;
  1379. X    packargs[2]=(ULONG)ptr >> 2L;
  1380. X    packargs[3]=(long)date;
  1381. X    SendPacket(ACTION_SET_DATE,packargs,task);
  1382. X    UnLock(dirlock);
  1383. X    FreeMem(ptr,65L);
  1384. X    }
  1385. Xreturn 0;
  1386. X}
  1387. X
  1388. Xdo_addbuffers()
  1389. X{
  1390. Xlong packargs[7];
  1391. Xlong n;
  1392. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1393. X
  1394. Xif (!task) { ierror(av[1],510); return 20; }
  1395. Xn=myatoi(av[2],1,32767); if (atoierr) return 20;
  1396. Xpackargs[0]=n;
  1397. XSendPacket(ACTION_MORE_CACHE,packargs,task);
  1398. Xreturn 0;
  1399. X}
  1400. X
  1401. Xdo_relabel()
  1402. X{
  1403. Xlong packargs[7];
  1404. XUBYTE *ptr;
  1405. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1406. X
  1407. Xif (!task) { ierror(av[1],510); return 20; }
  1408. Xptr=AllocMem(65L,MEMF_PUBLIC);
  1409. XCtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  1410. Xpackargs[0]=(ULONG)ptr >> 2L;
  1411. XSendPacket(ACTION_RENAME_DISK,packargs,task);
  1412. XFreeMem(ptr,65L);
  1413. Xchangedisk(task);
  1414. Xreturn 0;
  1415. X}
  1416. X
  1417. Xdo_diskchange()
  1418. X{
  1419. Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1420. X
  1421. Xif (!task) { ierror(av[1],510); return 20; }
  1422. Xchangedisk(task);
  1423. Xreturn 0;
  1424. X}
  1425. X
  1426. Xchangedisk(task)
  1427. Xstruct MsgPort *task;
  1428. X{
  1429. Xlong packargs[7];
  1430. X
  1431. Xpackargs[0]=1L;
  1432. XSendPacket(ACTION_INHIBIT,packargs,task);
  1433. Xpackargs[0]=0L;
  1434. XSendPacket(ACTION_INHIBIT,packargs,task);
  1435. X}
  1436. END_OF_FILE
  1437. if test 13095 -ne `wc -c <'src/comm2.c'`; then
  1438.     echo shar: \"'src/comm2.c'\" unpacked with wrong size!
  1439. fi
  1440. # end of 'src/comm2.c'
  1441. fi
  1442. if test -f 'src/sub.c' -a "${1}" != "-c" ; then 
  1443.   echo shar: Will not clobber existing file \"'src/sub.c'\"
  1444. else
  1445. echo shar: Extracting \"'src/sub.c'\" \(13255 characters\)
  1446. sed "s/^X//" >'src/sub.c' <<'END_OF_FILE'
  1447. X
  1448. X/*
  1449. X * SUB.C
  1450. X *
  1451. X * (c)1986 Matthew Dillon     9 October 1986
  1452. X *
  1453. X * Version 2.07M by Steve Drew 10-Sep-87
  1454. X *
  1455. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  1456. X *
  1457. X */
  1458. X
  1459. X#define HM_STR 0              /* various HISTORY retrieval modes */
  1460. X#define HM_REL 1
  1461. X#define HM_ABS 2
  1462. X
  1463. Xseterr()
  1464. X{
  1465. Xchar buf[32];
  1466. Xint stat;
  1467. X
  1468. Xsprintf(buf, "%d", Lastresult);
  1469. Xset_var(LEVEL_SET, v_lasterr, buf);
  1470. Xstat = atoi(get_var(LEVEL_SET, v_stat));
  1471. Xif (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
  1472. X}
  1473. X
  1474. X#define ISSPACE(c) ((c)==' ' || (c)==9 || (unsigned char)(c)==0xA0)
  1475. X
  1476. Xchar *next_word(str)
  1477. Xregister char *str;
  1478. X{
  1479. Xwhile (*str && ! ISSPACE(*str)) ++str;
  1480. Xwhile (*str &&   ISSPACE(*str)) ++str;
  1481. Xreturn str;
  1482. X}
  1483. X
  1484. Xhasspace(s)
  1485. Xregister char *s;
  1486. X{
  1487. Xfor ( ; *s; s++)
  1488. X    if (ISSPACE(*s)) return 1;
  1489. Xreturn 0;
  1490. X}
  1491. X
  1492. Xchar *compile_av(av, start, end, delim, quote)
  1493. Xchar **av;
  1494. Xunsigned char delim;
  1495. X{
  1496. Xregister char *cstr, *p;
  1497. Xint len;
  1498. Xregister unsigned int i;
  1499. X
  1500. Xlen = 1;
  1501. Xfor (i = start; i < end; ++i) len += strlen(av[i]) + 3;
  1502. Xp = cstr = malloc(len);
  1503. X*cstr = '\0';
  1504. Xfor (i = start; i < end; ++i) {
  1505. X    if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
  1506. X    if (quote && hasspace(av[i]))
  1507. X        p += sprintf(p, "\"%s\"", av[i]);
  1508. X    else
  1509. X        p += sprintf(p, "%s",     av[i]);
  1510. X    if (i+1 < end) *p++=delim;
  1511. X    }
  1512. X*p='\0';
  1513. Xreturn cstr;
  1514. X}
  1515. X
  1516. X/*
  1517. X * FREE(ptr)   --frees without actually freeing, so the data is still good
  1518. X *               immediately after the free.
  1519. X */
  1520. X
  1521. X
  1522. XFree(ptr)
  1523. Xchar *ptr;
  1524. X{
  1525. Xstatic char *old_ptr;
  1526. X
  1527. Xif (old_ptr) free (old_ptr);
  1528. Xold_ptr = ptr;
  1529. X}
  1530. X
  1531. X/*
  1532. X * Add new string to history (H_head, H_tail, H_len,
  1533. X *  S_histlen
  1534. X */
  1535. X
  1536. Xadd_history(str)
  1537. Xchar *str;
  1538. X{
  1539. X   register struct HIST *hist;
  1540. X
  1541. X   if (H_head != NULL && strcmp(H_head->line, str) == 0)
  1542. X       return(0);
  1543. X   while (H_len > S_histlen)
  1544. X      del_history();
  1545. X   hist = (struct HIST *)malloc (sizeof(struct HIST));
  1546. X   if (H_head == NULL) {
  1547. X      H_head = H_tail = hist;
  1548. X      hist->next = NULL;
  1549. X   } else {
  1550. X      hist->next = H_head;
  1551. X      H_head->prev = hist;
  1552. X      H_head = hist;
  1553. X   }
  1554. X   hist->prev = NULL;
  1555. X   hist->line = malloc (strlen(str) + 1);
  1556. X   strcpy (hist->line, str);
  1557. X   ++H_len;
  1558. X}
  1559. X
  1560. Xdel_history()
  1561. X{
  1562. X   if (H_tail) {
  1563. X      --H_len;
  1564. X      ++H_tail_base;
  1565. X      free (H_tail->line);
  1566. X      if (H_tail->prev) {
  1567. X         H_tail = H_tail->prev;
  1568. X         free (H_tail->next);
  1569. X         H_tail->next = NULL;
  1570. X      } else {
  1571. X         free (H_tail);
  1572. X         H_tail = H_head = NULL;
  1573. X      }
  1574. X   }
  1575. X}
  1576. X
  1577. Xchar *
  1578. Xget_history(ptr)
  1579. Xchar *ptr;
  1580. X{
  1581. X   register struct HIST *hist;
  1582. X   register int len;
  1583. X   int mode = HM_REL;
  1584. X   int num  = 1;
  1585. X   char *str;
  1586. X   char *result = NULL;
  1587. X
  1588. X   if (ptr[1] >= '0' && ptr[1] <= '9') {
  1589. X      mode = HM_ABS;
  1590. X      num  = atoi(&ptr[1]);
  1591. X      goto skip;
  1592. X   }
  1593. X   switch (ptr[1]) {
  1594. X   case '!':
  1595. X      break;
  1596. X   case '-':
  1597. X      num += atoi(&ptr[2]);
  1598. X      break;
  1599. X   default:
  1600. X      mode = HM_STR;
  1601. X      str  = ptr + 1;
  1602. X      break;
  1603. X   }
  1604. Xskip:
  1605. X   switch (mode) {
  1606. X   case HM_STR:
  1607. X      len = strlen(str);
  1608. X      for (hist = H_head; hist; hist = hist->next) {
  1609. X         if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
  1610. X            result = hist->line;
  1611. X            break;
  1612. X         }
  1613. X      }
  1614. X      break;
  1615. X   case HM_REL:
  1616. X      for (hist = H_head; hist && num--; hist = hist->next);
  1617. X      if (hist)
  1618. X         result = hist->line;
  1619. X      break;
  1620. X   case HM_ABS:
  1621. X      len = H_tail_base;
  1622. X      for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
  1623. X      if (hist)
  1624. X         result = hist->line;
  1625. X      break;
  1626. X   }
  1627. X   if (result) {
  1628. X      fprintf(stderr,"%s\n",result);
  1629. X      return(result);
  1630. X   }
  1631. X   printf("History failed\n");
  1632. X   return ("");
  1633. X}
  1634. X
  1635. Xreplace_head(str)
  1636. Xchar *str;
  1637. X{
  1638. X   if (str == NULL)
  1639. X      str = "";
  1640. X   if (H_head) {
  1641. X      free (H_head->line);
  1642. X      H_head->line = malloc (strlen(str)+1);
  1643. X      strcpy (H_head->line, str);
  1644. X   }
  1645. X}
  1646. X
  1647. X
  1648. XpError(str)
  1649. Xchar *str;
  1650. X{
  1651. Xint ierr = (long)IoErr();
  1652. Xierror(str, ierr);
  1653. X}
  1654. X
  1655. Xierror(str, err)
  1656. Xregister char *str;
  1657. X{
  1658. X   register struct PERROR *per = Perror;
  1659. X
  1660. X   if (err) {
  1661. X      for (; per->errstr; ++per) {
  1662. X         if (per->errnum == err) {
  1663. X            fprintf (stderr, "%s%s%s\n",
  1664. X                  per->errstr,
  1665. X                  (str) ? ": " : "",
  1666. X                  (str) ? str : "");
  1667. X            return ((short)err);
  1668. X         }
  1669. X      }
  1670. X      fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
  1671. X   }
  1672. X   return ((short)err);
  1673. X}
  1674. X
  1675. X/*
  1676. X * Disk directory routines
  1677. X *
  1678. X * dptr = dopen(name, stat)
  1679. X *    struct DPTR *dptr;
  1680. X *    char *name;
  1681. X *    int *stat;
  1682. X *
  1683. X * dnext(dptr, name, stat)
  1684. X *    struct DPTR *dptr;
  1685. X *    char **name;
  1686. X *    int  *stat;
  1687. X *
  1688. X * dclose(dptr)                  -may be called with NULL without harm
  1689. X *
  1690. X * dopen() returns a struct DPTR, or NULL if the given file does not
  1691. X * exist.  stat will be set to 1 if the file is a directory.  If the
  1692. X * name is "", then the current directory is openned.
  1693. X *
  1694. X * dnext() returns 1 until there are no more entries.  The **name and
  1695. X * *stat are set.  *stat = 1 if the file is a directory.
  1696. X *
  1697. X * dclose() closes a directory channel.
  1698. X *
  1699. X */
  1700. X
  1701. Xstruct DPTR *
  1702. Xdopen(name, stat)
  1703. Xchar *name;
  1704. Xint *stat;
  1705. X{
  1706. Xstruct DPTR *dp;
  1707. X
  1708. X*stat = 0;
  1709. Xdp = (struct DPTR *)malloc(sizeof(struct DPTR));
  1710. Xif (*name == '\0')
  1711. X    dp->lock = DupLock(Myprocess->pr_CurrentDir);
  1712. Xelse
  1713. X    dp->lock = Lock (name,ACCESS_READ);
  1714. Xif (dp->lock == NULL) {
  1715. X    free (dp);
  1716. X    return NULL;
  1717. X    }
  1718. Xdp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1719. Xif (!Examine (dp->lock, dp->fib)) {
  1720. X    pError (name);
  1721. X    dclose (dp);
  1722. X    return NULL;
  1723. X    }
  1724. Xif (dp->fib->fib_DirEntryType >= 0) *stat = 1;
  1725. Xreturn dp;
  1726. X}
  1727. X
  1728. Xdnext(dp, pname, stat)
  1729. Xstruct DPTR *dp;
  1730. Xchar **pname;
  1731. Xint *stat;
  1732. X{
  1733. Xif (dp == NULL) return (0);
  1734. X   if (ExNext (dp->lock, dp->fib)) {
  1735. X      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
  1736. X      *pname = dp->fib->fib_FileName;
  1737. X      return (1);
  1738. X   }
  1739. X   return (0);
  1740. X}
  1741. X
  1742. X
  1743. Xdclose(dp)
  1744. Xstruct DPTR *dp;
  1745. X{
  1746. X   if (dp == NULL)
  1747. X      return (1);
  1748. X   if (dp->fib)
  1749. X      FreeMem (dp->fib,(long)sizeof(*dp->fib));
  1750. X   if (dp->lock)
  1751. X      UnLock (dp->lock);
  1752. X   free (dp);
  1753. X   return (1);
  1754. X}
  1755. X
  1756. X
  1757. Xisdir(file)
  1758. Xchar *file;
  1759. X{
  1760. X   register struct DPTR *dp;
  1761. X   int stat;
  1762. X
  1763. X   stat = 0;
  1764. X   if (dp = dopen (file, &stat))
  1765. X      dclose(dp);
  1766. X   return (stat == 1);
  1767. X}
  1768. X
  1769. X
  1770. Xfree_expand(av)
  1771. Xregister char **av;
  1772. X{
  1773. X   char **base = av;
  1774. X
  1775. X   if (av) {
  1776. X      while (*av) {
  1777. X         free (*av);
  1778. X         ++av;
  1779. X      }
  1780. X      free (base);
  1781. X   }
  1782. X}
  1783. X
  1784. X/*
  1785. X * EXPAND(base,pac)
  1786. X *    base           - char * (example: "df0:*.c")
  1787. X *    pac            - int  *  will be set to # of arguments.
  1788. X *
  1789. X * 22-May-87 SJD.  Heavily modified to allow recursive wild carding and
  1790. X *                 simple directory/file lookups. Returns a pointer to
  1791. X *                 an array of pointers that contains the full file spec
  1792. X *                 eg. 'df0:c/sear*' would result in : 'df0:C/Search'
  1793. X *
  1794. X *                 Now no longer necessary to Examine the files a second time
  1795. X *                 in do_dir since expand will return the full file info
  1796. X *                 appended to the file name. Set by formatfile().
  1797. X *                 eg. fullfilename'\0'rwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS
  1798. X *
  1799. X *                 Caller must call free_expand when done with the array.
  1800. X *
  1801. X * base             bname =       ename =
  1802. X * ------           -------       -------
  1803. X *  "*"               ""            "*"
  1804. X *  "!*.info"         ""            "*.info" (wild_exclude set)
  1805. X *  "su*d/*"          ""            "*"      (tail set)
  1806. X *  "file.*"          ""            "file.*"
  1807. X *  "df0:c/*"         "df0:c"       "*"
  1808. X *  ""                ""            "*"
  1809. X *  "df0:.../*"       "df0:"        "*"      (recur set)
  1810. X *  "df0:sub/.../*"   "df0:sub"     "*"      (recur set)
  1811. X *
  1812. X * ---the above base would be provided by execom.c or do_dir().
  1813. X * ---the below base would only be called from do_dir().
  1814. X *
  1815. X *  "file.c"          "file.c"      ""       if (dp == 0) fail else get file.c
  1816. X *  "df0:"            "df0:"        "*"
  1817. X *  "file/file"       "file/file"   ""       (dp == 0) so fail
  1818. X *  "df0:.../"        "df0:"        "*"      (recur set)
  1819. X *
  1820. X */
  1821. X
  1822. X
  1823. Xchar **
  1824. Xexpand(base, pac)
  1825. Xchar *base;
  1826. Xint *pac;
  1827. X{
  1828. X   register char *ptr;
  1829. X   char **eav = (char **)malloc(sizeof(char *) * (2));
  1830. X   short eleft, eac;
  1831. X   char *name;
  1832. X   char *svfile();
  1833. X   char *bname, *ename, *tail;
  1834. X   int stat, recur, scr, bl;
  1835. X   register struct DPTR *dp;
  1836. X
  1837. X   *pac = recur = eleft = eac = 0;
  1838. X
  1839. X   base = strcpy(malloc(strlen(base)+1), base);
  1840. X   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
  1841. X
  1842. X   if (!*ptr)   /* no wild cards */
  1843. X      --ptr;
  1844. X   else
  1845. X      for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
  1846. X
  1847. X   if (ptr < base) {
  1848. X      bname = strcpy (malloc(1), "");
  1849. X   } else {
  1850. X      scr = ptr[1];
  1851. X      ptr[1] = '\0';
  1852. X      if (!strcmp(ptr-3,".../")) {
  1853. X         recur = 1;
  1854. X         *(ptr-3) = '\0';
  1855. X      }
  1856. X      bname = strcpy (malloc(strlen(base)+2), base);
  1857. X      ptr[1] = scr;
  1858. X   }
  1859. X   bl = strlen(bname);
  1860. X   ename = ++ptr;
  1861. X   for (; *ptr && *ptr != '/'; ++ptr);
  1862. X   scr = *ptr;
  1863. X   *ptr = '\0';
  1864. X   if (scr) ++ptr;
  1865. X   tail = ptr;
  1866. X
  1867. X   if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
  1868. X      free (bname);
  1869. X      free (base);
  1870. X      free (eav);
  1871. X      return (NULL);
  1872. X   }
  1873. X
  1874. X   if (!stat) {                /* eg. 'dir file' */
  1875. X      char *p,*s;
  1876. X      for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
  1877. X      if (s != bname) ++s;
  1878. X      *s ='\0';
  1879. X      eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
  1880. X      goto done;
  1881. X   }
  1882. X   if (!*ename) ename = "*";    /* eg. dir df0: */
  1883. X   if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
  1884. X      bname[bl] = '/';
  1885. X      bname[++bl] = '\0';
  1886. X   }
  1887. X   while ((dnext (dp, &name, &stat)) && !breakcheck()) {
  1888. X        int match = compare_ok(ename,name,0);
  1889. X      if (match && !(!recur && *tail)) {
  1890. X         if (eleft < 2) {
  1891. X               char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  1892. X               movmem (eav, scrav, (eac + 1) << 2);
  1893. X               free (eav);
  1894. X               eav = scrav;
  1895. X               eleft = 10;
  1896. X         }
  1897. X         eav[eac++] = svfile(bname,name,dp->fib);
  1898. X         --eleft;
  1899. X      }
  1900. X      if ((*tail && match) || recur) {
  1901. X         int alt_ac;
  1902. X         char *search, **alt_av, **scrav;
  1903. X         BPTR lock;
  1904. X
  1905. X         if (!stat)           /* expect more dirs, but this not a dir */
  1906. X            continue;
  1907. X         lock = CurrentDir (dp->lock);
  1908. X         search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
  1909. X         strcpy (search, name);
  1910. X         strcat (search, "/");
  1911. X         if (recur) {
  1912. X            strcat(search, ".../");
  1913. X            strcat(search, ename);
  1914. X         }
  1915. X         strcat (search, tail);
  1916. X         scrav = alt_av = expand (search, &alt_ac);
  1917. X         /* free(search); */
  1918. X         CurrentDir (lock);
  1919. X         if (scrav) {
  1920. X            while (*scrav) {
  1921. X               int l;
  1922. X               if (eleft < 2) {
  1923. X                  char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  1924. X                  movmem (eav, scrav, (eac + 1) << 2);
  1925. X                  free (eav);
  1926. X                  eav = scrav;
  1927. X                  eleft = 10;
  1928. X               }
  1929. X
  1930. X               l = strlen(*scrav);
  1931. X               scrav[0][l] = ' ';
  1932. X               eav[eac] = malloc(bl+l+45);
  1933. X               strcpy(eav[eac], bname);
  1934. X               strcat(eav[eac], *scrav);
  1935. X               eav[eac][l+bl] = '\0';
  1936. X
  1937. X               free (*scrav);
  1938. X               ++scrav;
  1939. X               --eleft, ++eac;
  1940. X            }
  1941. X            free (alt_av);
  1942. X         }
  1943. X      }
  1944. X   }
  1945. Xdone:
  1946. X   dclose (dp);
  1947. X   *pac = eac;
  1948. X   eav[eac] = NULL;
  1949. X   free (bname);
  1950. X   free (base);
  1951. X   if (eac) {
  1952. X      return (eav);
  1953. X   }
  1954. X   free (eav);
  1955. X   return (NULL);
  1956. X}
  1957. X
  1958. Xstrupr(s)
  1959. Xregister char *s;
  1960. X{
  1961. Xwhile (*s) *s=toupper(*s), s++;
  1962. X}
  1963. X
  1964. X/*
  1965. X * Compare a wild card name with a normal name
  1966. X */
  1967. X
  1968. Xcompare_ok(wild, name, casedep)
  1969. Xchar *wild, *name;
  1970. X{
  1971. Xint queryflag;
  1972. Xchar buf[260], wildbuf[260], *lowname;
  1973. X
  1974. Xif (queryflag=(*wild=='&')) wild++;
  1975. Xif (*wild=='!') *wild='~';
  1976. X
  1977. Xif (! casedep) {
  1978. X    strupr(wild);
  1979. X    strcpy(buf,name);
  1980. X    strupr(buf);
  1981. X    lowname=buf;
  1982. X    }
  1983. Xelse lowname=name;
  1984. X
  1985. XPreParse(wild, wildbuf);
  1986. Xif ( ! PatternMatch(wildbuf,lowname)) return 0;
  1987. X
  1988. Xif (queryflag) {
  1989. X    printf("Select \23337m%-16s\2330m [y/n] ? ",name);
  1990. X    gets(buf);
  1991. X    return (toupper(*buf)=='Y');
  1992. X    }
  1993. Xreturn 1;
  1994. X}
  1995. X
  1996. Xchar *svfile(s1,s2,fib)
  1997. Xchar *s1,*s2;
  1998. XFIB *fib;
  1999. X{
  2000. Xchar *p = malloc (strlen(s1)+strlen(s2)+45);
  2001. Xstrcpy(p, s1);
  2002. Xstrcat(p, s2);
  2003. Xformatfile(p,fib);
  2004. Xreturn p;
  2005. X}
  2006. X
  2007. X/* will have either of these formats:
  2008. X *
  2009. X *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  2010. X *    fullfilename'\0'hsparwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  2011. X *                              1111111111222222222233333333334 4  4
  2012. X *                    01234567890123456789012345678901234567890 1  2
  2013. X */
  2014. Xformatfile(str,fib)
  2015. Xchar *str;
  2016. XFIB *fib;
  2017. X{
  2018. Xchar *dates();
  2019. Xint i;
  2020. Xwhile(*str++);
  2021. Xfor (i=7; i>=0; i--)
  2022. X    *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
  2023. Xif (fib->fib_DirEntryType < 0)
  2024. X  sprintf(str,"  %6ld %4ld  ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
  2025. Xelse strcpy(str,"   <Dir>       ");
  2026. Xstrcat(str,dates(&fib->fib_Date));
  2027. X}
  2028. X
  2029. X/* Sort routines */
  2030. X
  2031. Xlong cmp(s1, s2)
  2032. Xchar **s1, **s2;
  2033. X{
  2034. Xreturn (long)Strcmp(*s1, *s2);
  2035. X}
  2036. X
  2037. XCmp() {
  2038. X#asm
  2039. X    public    _geta4
  2040. X    movem.l    d2-d3/a4/a6,-(sp)
  2041. X    movem.l    a0/a1,-(sp)
  2042. X    bsr    _geta4
  2043. X    bsr    _cmp
  2044. X    addq.l    #8,sp
  2045. X    movem.l    (sp)+,d2-d3/a4/a6
  2046. X#endasm
  2047. X}
  2048. X
  2049. XQuickSort(av, n)
  2050. Xchar *av[];
  2051. Xint n;
  2052. X{
  2053. XQSort(av, (long)n, 4L, Cmp);
  2054. X}
  2055. END_OF_FILE
  2056. if test 13255 -ne `wc -c <'src/sub.c'`; then
  2057.     echo shar: \"'src/sub.c'\" unpacked with wrong size!
  2058. fi
  2059. # end of 'src/sub.c'
  2060. fi
  2061. echo shar: End of archive 2 \(of 4\).
  2062. cp /dev/null ark2isdone
  2063. MISSING=""
  2064. for I in 1 2 3 4 ; do
  2065.     if test ! -f ark${I}isdone ; then
  2066.     MISSING="${MISSING} ${I}"
  2067.     fi
  2068. done
  2069. if test "${MISSING}" = "" ; then
  2070.     echo You have unpacked all 4 archives.
  2071.     rm -f ark[1-9]isdone
  2072. else
  2073.     echo You still need to unpack the following archives:
  2074.     echo "        " ${MISSING}
  2075. fi
  2076. ##  End of shell archive.
  2077. exit 0
  2078. -- 
  2079. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  2080. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  2081. Post requests for sources, and general discussion to comp.sys.amiga.
  2082.